/*
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.matezk.dms.things.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.net.URLEncoder;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.matezk.dms.things.mapper.DeviceMapper;
import cn.matezk.dms.things.mapper.SimCardMapper;
import cn.matezk.dms.things.model.entity.SimCardDO;
import cn.matezk.dms.things.model.query.SimCardQuery;
import cn.matezk.dms.things.model.req.SimCardReq;
import cn.matezk.dms.things.model.resp.SimCardDetailResp;
import cn.matezk.dms.things.model.resp.SimCardResp;
import cn.matezk.dms.things.service.SimCardService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.continew.starter.extension.crud.service.impl.BaseServiceImpl;

import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 物联网卡业务实现
 *
 * @author 程道林
 * @since 2025/08/28 22:10
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SimCardServiceImpl extends BaseServiceImpl<SimCardMapper, SimCardDO, SimCardResp, SimCardDetailResp, SimCardQuery, SimCardReq> implements SimCardService {
    @Autowired
    private SimCardMapper simCardMapper;
    @Autowired
    private DeviceMapper deviceMapper;

    //    @PostConstruct
    public void execute() throws InterruptedException {
        new Thread(() -> {
            syncFromWs("nEFhrTciiXP", "admin@108827", "277171");
        }).start();
        new Thread(() -> {
            syncFromEz("CDMTZKKJYXGS1184@2024", "437bebe90638a6a3", "fa6fb09698305e9c");
        }).start();
        new Thread(() -> {
            try {
                syncFromDy("Bearer eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImU3NDk0NzI0LWI5NWUtNDU0OS05ZjdhLTYzZGY5OWQ1NTAwNCJ9.EbS8_6JIYpDLytt7cNaXfv5cZXgvN4JtpyksdlYFwQ0CTC5tKTznzODcEoSZlNmivxgzkrq7jBaDh7rvcYdQVA");
            } catch (InterruptedException e) {
                log.error(e.getMessage());
            }
        }).start();
    }

    @Override
    public void syncFromWs(String appId, String account, String password) {
        List<String> iccids = deviceMapper.selectUnknowIccid();
        if (ObjectUtil.isEmpty(iccids))
            return;
        Map<String, Object> form = new HashMap<>();
        form.put("amount", account);
        form.put("key", MD5.create().digestHex(password));
        List<List<String>> array = CollectionUtil.split(iccids, 100);

        for (List<String> batch : array) {
            form.put("iccids", String.join("_", batch));
            try {
                String body = HttpUtil.get("http://tools.wosoiot.com:8080/interfaces/v1/batch/cardInfo.action", form);
                JSONObject object = JSONUtil.parseObj(body);
                if (object.containsKey("data")) {
                    JSONArray list = object.getJSONArray("data");
                    if (array.size() == 0)
                        continue;
                    for (int i = 0; i < list.size(); i++) {
                        JSONObject item = list.getJSONObject(i);
                        if (!"1".equals(item.getStr("status")))
                            continue;
                        SimCardDO simCard = new SimCardDO();
                        simCard.setId(IdUtil.getSnowflakeNextId());
                        simCard.setAppId(appId);
                        simCard.setPlatform("WS");
                        simCard.setIccid(item.getStr("iccid"));
                        simCard.setPkgName(item.getStr("catename"));
                        simCard.setUsedFlow(item.getBigDecimal("gprs_use", BigDecimal.valueOf(0)));
                        Pattern pattern = Pattern.compile("\\d+");
                        Matcher matcher = pattern.matcher(simCard.getPkgName());
                        if (matcher.find()) {
                            BigDecimal total = new BigDecimal(matcher.group());
                            simCard.setUsableFlow(total.subtract(simCard.getUsedFlow()));
                        }
                        String status = item.getStr("card_status");
                        if (ObjectUtil.equals("00", status)) {
                            simCard.setCardStatus("正常");
                        } else if (ObjectUtil.equals("01", status)) {
                            simCard.setCardStatus("单向停机");
                        } else if (ObjectUtil.equals("02", status)) {
                            simCard.setCardStatus("停机");
                        } else if (ObjectUtil.equals("03", status)) {
                            simCard.setCardStatus("预销户");
                        } else if (ObjectUtil.equals("07", status)) {
                            simCard.setCardStatus("待激活");
                        }
                        simCard.setActiveDate(item.getDate("activate_time"));
                        simCard.setExpireDate(item.getDate("expire_time"));
                        simCard.setSyncTime(new Date());
                        simCardMapper.insert(simCard);
                    }
                }
            } catch (Exception e) {
                log.error("同步握手平台流量卡异常", e);
            }
        }
    }

    @Override
    public void syncFromDy(String token) throws InterruptedException {
        List<String> iccids = deviceMapper.selectUnknowIccid();
        if (ObjectUtil.isEmpty(iccids))
            return;
        List<List<String>> array = CollectionUtil.split(iccids, 100);
        for (List<String> batch : array) {
            HttpResponse response = HttpRequest.post("https://5giot.cn/prod-api/open/iotCard/detail/batch")
                .body(JSONUtil.createObj().set("iccidList", batch).toString())
                .header(Header.AUTHORIZATION, token)
                .execute();
            if (!response.isOk())
                continue;
            JSONObject object = JSONUtil.parseObj(response.body());
            if (object.getInt("code") != 200) {
                log.error(response.body());
                break;
            }
            JSONArray data = object.getJSONArray("data");
            for (int i = 0; i < data.size(); i++) {
                JSONObject item = data.getJSONObject(i);
                SimCardDO simCard = new SimCardDO();
                simCard.setId(IdUtil.getSnowflakeNextId());
                simCard.setAppId("nEFhrTciiXP");
                simCard.setPlatform("DY");
                simCard.setIccid(item.getStr("iccid"));
                simCard.setPkgName(item.getStr("flowSpecification"));
                simCard.setUsedFlow(item.getBigDecimal("useDataVolume", BigDecimal.valueOf(0)));
                Pattern pattern = Pattern.compile("\\d+");
                Matcher matcher = pattern.matcher(simCard.getPkgName());
                if (matcher.find()) {
                    BigDecimal total = new BigDecimal(matcher.group());
                    simCard.setUsableFlow(total.subtract(simCard.getUsedFlow()));
                }
                simCard.setCardStatus(item.getStr("cardStatus"));
                simCard.setActiveDate(item.getDate("startDate"));
                simCard.setExpireDate(item.getDate("expireDate"));
                simCard.setSyncTime(new Date());
                simCardMapper.insert(simCard);
            }
            Thread.sleep(1000 * 10);
        }
    }

    @Override
    public void syncFromEz(String apiId, String apiKey, String apiPwd) {
        // 删除老数据
        simCardMapper.deleteByPlatform("EZ");

        Map<String, Object> form = new HashMap<>();
        form.put("id", apiId);
        int pageNo = 0;
        while (true) {
            String body = JSONUtil.createObj()
                .set("pwd", apiPwd)
                .set("method", "getSIMList")
                .set("pageIndex", pageNo++)
                .set("cardType", "4G")
                .toString();
            form.put("info", XorEncryptAndBaseNew(body, apiKey));
            String response = HttpUtil.post("http://global.anhuiyk.cn:8006/m2m_api/v1/query/", form);
            JSONObject obj = JSONUtil.parseObj(response);
            if (!"0".equals(obj.getStr("resultCode")))
                break;
            JSONObject description = obj.getJSONObject("description");
            if (ObjectUtil.isEmpty(description))
                break;
            JSONArray array = description.getJSONArray("simList");
            if (ObjectUtil.isEmpty(array) || array.size() == 0)
                break;
            for (int i = 0; i < array.size(); i++) {
                JSONObject item = array.getJSONObject(i);
                SimCardDO simCard = new SimCardDO();
                simCard.setId(IdUtil.getSnowflakeNextId());
                simCard.setAppId("nEFhrTciiXP");
                simCard.setPlatform("EZ");
                simCard.setIccid(item.getStr("iccid"));
                simCard.setPkgName(item.getStr("p_name"));
                simCard.setUsedFlow(item.getBigDecimal("totalVolumnGPRS", BigDecimal.valueOf(0))
                    .divide(BigDecimal.valueOf(1024 * 1024)));
                Pattern pattern = Pattern.compile("(\\d+)(?i)m");
                Matcher matcher = pattern.matcher(simCard.getPkgName());
                if (matcher.find()) {
                    BigDecimal total = new BigDecimal(matcher.group().replace("m", "").replace("M", ""));
                    simCard.setUsableFlow(total.subtract(simCard.getUsedFlow()));
                }
                simCard.setCardStatus(item.getStr("simStatus"));
                simCard.setActiveDate(item.getDate("activate_date"));

                Date expireDate = item.getDate("serviceEndTime");
                if (ObjectUtil.isNotNull(expireDate)) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(expireDate);
                    if (calendar.get(Calendar.DATE) == 1) {
                        calendar.add(Calendar.DATE, -1);
                    }
                    simCard.setExpireDate(calendar.getTime());
                }
                simCard.setSyncTime(new Date());
                simCardMapper.insert(simCard);
            }
            if (array.size() == 0)
                break;
        }
    }

    public static String XorEncryptAndBaseNew(String str, String key) {
        byte[] b1 = str.getBytes();
        byte[] b2 = key.getBytes();
        byte[] out = new byte[b1.length];
        for (int i = 0; i < b1.length; i++) {
            out[i] = (byte)(b1[i] ^ b2[i % b2.length]);
        }
        return new URLEncoder().encode(Base64.getEncoder().encodeToString(out), Charset.defaultCharset());
    }
}